package com.qf.factory;

import com.qf.service.AccountService;
import com.qf.utils.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Description: 公用常量
 * @Data: 2022/8/31 19:08
 * @Pacakge: com.qf.factory
 * @ClassName: BeanFactory
 * @Author: fan
 * 用来生成代理对象
 */
public class BeanFactory {
    private AccountService accountService;

    private TransactionManager transactionManager;

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public void setAccountService(AccountService accountService) {
        this.accountService = accountService;
    }

    //生成代理对象
    public AccountService getBean(){
        //代理对象
        /**
         * 第一个参数:类加载器 目标类的类加载器 目标对象.getClass().getClassLoader()
         * 第二个参数:字节码数组 (目标对象实现的接口的字节码) 目标对象.getClass().getInterface()获取目标锁所实现的接口
         * 第三个参数:增强业务逻辑
         */
        AccountService o = (AccountService) Proxy.newProxyInstance(
                accountService.getClass().getClassLoader(),
                accountService.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 执行被代理接口的任何方法,都会执行该方法
                     * @param proxy 当前代理对象的引用,一般较少使用
                     * @param method 当前执行的方法
                     * @param args 当前执行方法需要的参数
                     * @return 和被代理对象一样的返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if ("transfer".equals(method.getName())){
                            try {
                                //开启事务
                                transactionManager.beginTransaction();
                                //目标方法的执行
                                method.invoke(accountService,args);
                                //提交事务
                                transactionManager.commitTransaction();
                            } catch (Exception e) {
                                //事务回滚
                                transactionManager.rollbackTransaction();
                                e.printStackTrace();
                            }finally{
                                //释放资源
                                transactionManager.release();
                            }
                        }
                        return null;
                    }
                });
            return o;
    }

}
